//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V1.0.0
#include "button_driver.h"
#include <string.h>
#include <stdio.h>


static volatile WHT_Button_All_State_t WHT_All_Button_State = {0}; //所有按键的实时状态

#if Independent_Button_EN  //独立按键
    static volatile uint32_t* Get_Independent_Button_State[Independent_Button_Count] = {NULL};
#endif

#if Matrix_Button_EN    //矩阵按键
    static volatile uint32_t* Set_Matrix_Button_Row_State[Matrix_Button_Row] = {NULL};
    static volatile uint32_t* Get_Matrix_Button_Col_State[Matrix_Button_Col] = {NULL};
#endif


static void WHT_Button_Driver_GPIO_Init(void)
{
#if Independent_Button_EN  //独立按键
	WHT_GPIO_BSP.WHT_Set_Clock(Independent_Button0_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Independent_Button1_GPIO_Port, ENABLE);

	WHT_GPIO_BSP.WHT_Register_Bit_Input(Independent_Button0_GPIO_Port, Independent_Button0_GPIO_Pin, &Get_Independent_Button_State[Independent_Button0]);
	WHT_GPIO_BSP.WHT_Register_Bit_Input(Independent_Button1_GPIO_Port, Independent_Button1_GPIO_Pin, &Get_Independent_Button_State[Independent_Button1]);
	
    WHT_GPIO_BSP.WHT_Set_Mode(Independent_Button0_GPIO_Port, Independent_Button0_GPIO_Pin, Mode_In_FLOATING);
	WHT_GPIO_BSP.WHT_Set_Mode(Independent_Button1_GPIO_Port, Independent_Button1_GPIO_Pin, Mode_In_FLOATING);
#endif

#if Matrix_Button_EN    //矩阵按键
    //行配置
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_Button_ROW0_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_Button_ROW1_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_Button_ROW2_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_Button_ROW3_GPIO_Port, ENABLE);

	WHT_GPIO_BSP.WHT_Register_Bit_Output(Matrix_Button_ROW0_GPIO_Port, Matrix_Button_ROW0_GPIO_Pin, &Set_Matrix_Button_Row_State[0]);
	WHT_GPIO_BSP.WHT_Register_Bit_Output(Matrix_Button_ROW1_GPIO_Port, Matrix_Button_ROW1_GPIO_Pin, &Set_Matrix_Button_Row_State[1]);
	WHT_GPIO_BSP.WHT_Register_Bit_Output(Matrix_Button_ROW2_GPIO_Port, Matrix_Button_ROW2_GPIO_Pin, &Set_Matrix_Button_Row_State[2]);
	WHT_GPIO_BSP.WHT_Register_Bit_Output(Matrix_Button_ROW3_GPIO_Port, Matrix_Button_ROW3_GPIO_Pin, &Set_Matrix_Button_Row_State[3]);

    *Set_Matrix_Button_Row_State[0] = Hig;
    *Set_Matrix_Button_Row_State[1] = Hig;
    *Set_Matrix_Button_Row_State[2] = Hig;
    *Set_Matrix_Button_Row_State[3] = Hig;

	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_Button_ROW0_GPIO_Port, Matrix_Button_ROW0_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_Button_ROW1_GPIO_Port, Matrix_Button_ROW1_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_Button_ROW2_GPIO_Port, Matrix_Button_ROW2_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_Button_ROW3_GPIO_Port, Matrix_Button_ROW3_GPIO_Pin, Mode_Out_PP);
    //列配置
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_Button_COL0_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_Button_COL1_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_Button_COL2_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_Button_COL3_GPIO_Port, ENABLE);

	WHT_GPIO_BSP.WHT_Register_Bit_Input(Matrix_Button_COL0_GPIO_Port, Matrix_Button_COL0_GPIO_Pin, &Get_Matrix_Button_Col_State[0]);
	WHT_GPIO_BSP.WHT_Register_Bit_Input(Matrix_Button_COL1_GPIO_Port, Matrix_Button_COL0_GPIO_Pin, &Get_Matrix_Button_Col_State[1]);
	WHT_GPIO_BSP.WHT_Register_Bit_Input(Matrix_Button_COL2_GPIO_Port, Matrix_Button_COL0_GPIO_Pin, &Get_Matrix_Button_Col_State[2]);
	WHT_GPIO_BSP.WHT_Register_Bit_Input(Matrix_Button_COL3_GPIO_Port, Matrix_Button_COL0_GPIO_Pin, &Get_Matrix_Button_Col_State[3]);

	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_Button_COL0_GPIO_Port, Matrix_Button_COL0_GPIO_Pin, Mode_IPD);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_Button_COL1_GPIO_Port, Matrix_Button_COL1_GPIO_Pin, Mode_IPD);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_Button_COL2_GPIO_Port, Matrix_Button_COL2_GPIO_Pin, Mode_IPD);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_Button_COL3_GPIO_Port, Matrix_Button_COL3_GPIO_Pin, Mode_IPD);
#endif
    printf("WHT:Button GPIO Init OK!\r\n");
}

#if Independent_Button_EXTI_EN  //独立按键 外部中断
static void WHT_Independent_Button0_Exti_Callback(void);
static void WHT_Independent_Button1_Exti_Callback(void);

static volatile uint32_t WHT_Independent_Button_Exti_Flag = 0;//独立按键个数最大支持32个
static WHT_Button_Interrupt_Callback_t WHT_Independent_Button_Interrupt_Callback = NULL;
static const WHT_EXTI_Config_t WHT_Independent_Button_Config[Independent_Button_Count] =
{
	{Exti_GPIO,Independent_Button0_EXTI_Line,Trigger_Rising,Mode_Interrupt,WHT_Independent_Button0_Exti_Callback,Independent_Button0_GPIO_Port,Independent_Button0_GPIO_Pin},
	{Exti_GPIO,Independent_Button1_EXTI_Line,Trigger_Rising,Mode_Interrupt,WHT_Independent_Button1_Exti_Callback,Independent_Button1_GPIO_Port,Independent_Button1_GPIO_Pin},
};

static void WHT_Independent_Button_Exti_Start(WHT_Independent_Button_Number_enum number)
{
	WHT_Independent_Button_Exti_Flag &= ~(0x01 << number);//清零
	WHT_EXTI_BSP.WHT_Line_Cmd(&WHT_Independent_Button_Config[number], ENABLE);//开启此路中断功能
}
static void WHT_Independent_Button_Exti_Stop(WHT_Independent_Button_Number_enum number)
{
	WHT_Independent_Button_Exti_Flag |= 0x01 << number;//置位
	WHT_EXTI_BSP.WHT_Line_Cmd(&WHT_Independent_Button_Config[number], DISABLE);//关闭此路中断功能
	if (WHT_Independent_Button_Interrupt_Callback != NULL)
		WHT_Independent_Button_Interrupt_Callback();
}
static void WHT_Independent_Button0_Exti_Callback(void)
{
	WHT_Independent_Button_Exti_Stop(Independent_Button0);
}
static void WHT_Independent_Button1_Exti_Callback(void)
{
	WHT_Independent_Button_Exti_Stop(Independent_Button1);
}
static void WHT_Button_Driver_Independent_Button_Exti_Config(const WHT_Button_Interrupt_Callback_t interrupt_callback)
{
	uint8_t i;

	for (i = 0; i < Independent_Button_Count; i++)
	{
		//配置独立按键的引脚中断
		if (WHT_EXTI_BSP.WHT_Register(&WHT_Independent_Button_Config[i]) == SUCCESS)
		{
			WHT_EXTI_BSP.WHT_Config(&WHT_Independent_Button_Config[i]);
		} 
		else
		{
			printf("WHT:Independent Button %d Exti Config Error!\r\n", i);
			return;
		}
	}
	WHT_Independent_Button_Interrupt_Callback = interrupt_callback;
	printf("WHT:Independent Button Exti Config OK!\r\n");
}
#endif

#if Matrix_Button_EXTI_EN      //矩阵按键 外部中断
static void WHT_Matrix_Button_Col0_Exti_Callback(void);
static void WHT_Matrix_Button_Col1_Exti_Callback(void);
static void WHT_Matrix_Button_Col2_Exti_Callback(void);
static void WHT_Matrix_Button_Col3_Exti_Callback(void);

static volatile uint32_t WHT_Matrix_Button_Col_Exti_Flag = 0;//矩阵按键列数最大支持32
static WHT_Button_Interrupt_Callback_t WHT_Matrix_Button_Interrupt_Callback = NULL;
static const WHT_EXTI_Config_t WHT_Matrix_Button_Config[Matrix_Button_Col] =
{
	{Exti_GPIO,Matrix_Button_COL0_EXTI_Line,Trigger_Rising,Mode_Interrupt,WHT_Matrix_Button_Col0_Exti_Callback,Matrix_Button_COL0_GPIO_Port,Matrix_Button_COL0_GPIO_Pin},
	{Exti_GPIO,Matrix_Button_COL1_EXTI_Line,Trigger_Rising,Mode_Interrupt,WHT_Matrix_Button_Col1_Exti_Callback,Matrix_Button_COL1_GPIO_Port,Matrix_Button_COL1_GPIO_Pin},
	{Exti_GPIO,Matrix_Button_COL2_EXTI_Line,Trigger_Rising,Mode_Interrupt,WHT_Matrix_Button_Col2_Exti_Callback,Matrix_Button_COL2_GPIO_Port,Matrix_Button_COL2_GPIO_Pin},
	{Exti_GPIO,Matrix_Button_COL3_EXTI_Line,Trigger_Rising,Mode_Interrupt,WHT_Matrix_Button_Col3_Exti_Callback,Matrix_Button_COL3_GPIO_Port,Matrix_Button_COL3_GPIO_Pin},
};
static void WHT_Matrix_Button_Col_Exti_Start(WHT_Matrix_Button_Col_enum number)
{
	WHT_Matrix_Button_Col_Exti_Flag &= ~(0x01 << number);//清零
	WHT_EXTI_BSP.WHT_Line_Cmd(&WHT_Matrix_Button_Config[number], ENABLE);//开启此路中断功能
}
static void WHT_Matrix_Button_Col_Exti_Stop(WHT_Matrix_Button_Col_enum number)
{
	WHT_Matrix_Button_Col_Exti_Flag |= 0x01 << number;//置位
	WHT_EXTI_BSP.WHT_Line_Cmd(&WHT_Matrix_Button_Config[number], DISABLE);//关闭此路中断功能
	if (WHT_Matrix_Button_Interrupt_Callback != NULL)
		WHT_Matrix_Button_Interrupt_Callback();
}
static void WHT_Matrix_Button_Col0_Exti_Callback(void)
{
	WHT_Matrix_Button_Col_Exti_Stop(Matrix_Button_Col0);
}
static void WHT_Matrix_Button_Col1_Exti_Callback(void)
{
	WHT_Matrix_Button_Col_Exti_Stop(Matrix_Button_Col1);
}
static void WHT_Matrix_Button_Col2_Exti_Callback(void)
{
	WHT_Matrix_Button_Col_Exti_Stop(Matrix_Button_Col2);
}
static void WHT_Matrix_Button_Col3_Exti_Callback(void)
{
	WHT_Matrix_Button_Col_Exti_Stop(Matrix_Button_Col3);
}
static void WHT_Button_Driver_Matrix_Button_Col_Exti_Config(const WHT_Button_Interrupt_Callback_t interrupt_callback)
{
	uint8_t i;

	for (i = 0; i < Matrix_Button_Col; i++)
	{
		//配置矩阵按键列的引脚中断
		if (WHT_EXTI_BSP.WHT_Register(&WHT_Matrix_Button_Config[i]) == SUCCESS)
		{
			WHT_EXTI_BSP.WHT_Config(&WHT_Matrix_Button_Config[i]);
		} 
		else
		{
			printf("WHT:Matrix Button Col %d Exti Config Error!\r\n", i);
			return;
		}
	}
	WHT_Matrix_Button_Interrupt_Callback = interrupt_callback;
	printf("WHT:Matrix Button Exti Config OK!\r\n");
}
#endif

#if Independent_Button_EN      //独立按键
static WHT_Button_State_enum WHT_Button_Driver_Get_Independent_Button_State(void)
{
	uint8_t i;

	for (i = 0; i < Independent_Button_Count; i++)
	{
		if (*Get_Independent_Button_State[i] != Low)//按键按下，野火指南者是高电平按键按下
			return Button_Yes_Down;
	}
	return Button_No_Down;
}
static void WHT_Button_Driver_Independent_Button_Scan(WHT_Independent_Button_Number_enum number)
{
	uint8_t i;

	i = number == ALL_Independent_Button ? 0 : number;
	for (; i < Independent_Button_Count; i++)
	{
		if (*Get_Independent_Button_State[i] != Low)//按键按下，野火指南者是高电平按键按下
		{
			WHT_All_Button_State.Independent_Button_State[i].Down_Count++;
			if (WHT_All_Button_State.Independent_Button_State[i].state != Button_Yes_Down)
				WHT_All_Button_State.Independent_Button_State[i].state = Button_Yes_Down;//按下状态
		}
		else//按键松开或未按下
		{
			if (WHT_All_Button_State.Independent_Button_State[i].state == Button_Yes_Down)//判断之前按键状态
			{
				WHT_All_Button_State.Independent_Button_State[i].state = Button_Down_Up;//松手
				printf("WHT:Button Down is %d\r\n", WHT_All_Button_State.Independent_Button_State[i].Down_Count);
			}
		}
		if (number != ALL_Independent_Button)
			break;
	}
}
#endif

#if Matrix_Button_EN           //矩阵按键
static void WHT_Button_Drinver_Matrix_Button_Set_All_ROW_State(WHT_GPIO_State_enum state)
{
	uint8_t row;

	for (row = 0; row < Matrix_Button_Row; row++)
	{
		*Set_Matrix_Button_Row_State[row] = state;
	}
}
static WHT_Button_State_enum WHT_Button_Driver_Get_Matrix_Button_State(void)
{
	uint8_t col;

	for (col = 0; col < Matrix_Button_Col; col++)
	{
		if (*Get_Matrix_Button_Col_State[col] == Hig)//按键按下
			return Button_Yes_Down;
	}
	return Button_No_Down;
}
static void WHT_Button_Driver_Matrix_Button_Scan(WHT_Matrix_Button_Col_enum colx)
{
	static uint8_t row = 0;
	static uint8_t col = 0;

	col = colx == ALL_Matrix_Button_Col ? 0 : colx;
	WHT_Button_Drinver_Matrix_Button_Set_All_ROW_State(Low);//拉低所有行
	for (row = 0; row < Matrix_Button_Row; row++)//逐行扫描
	{
		*Set_Matrix_Button_Row_State[row] = Hig;
		for (; col < Matrix_Button_Col; col++)//逐列获取
		{
			if (*Get_Matrix_Button_Col_State[col] == Hig)//按键按下
			{
				WHT_All_Button_State.Matrix_Button_State[row][col].Down_Count++;
				if (WHT_All_Button_State.Matrix_Button_State[row][col].state != Button_Yes_Down)
					WHT_All_Button_State.Matrix_Button_State[row][col].state = Button_Yes_Down;//按下状态
			}
			else//按键松开或未按下
			{
				if (WHT_All_Button_State.Matrix_Button_State[row][col].state == Button_Yes_Down)//判断之前按键状态
					WHT_All_Button_State.Matrix_Button_State[row][col].state = Button_Down_Up;//松手
			}
			if (colx != ALL_Matrix_Button_Col) //只读取指定的列
				break;
		}
		*Set_Matrix_Button_Row_State[row] = Low;
	}
	WHT_Button_Drinver_Matrix_Button_Set_All_ROW_State(Hig);//拉高所有行
}
#endif


void WHT_Button_Driver_Register(WHT_Button_Driver_t* driver)
{
    WHT_Button_Driver_GPIO_Init();

	driver->WHT_Button_State = &WHT_All_Button_State;
#if Independent_Button_EXTI_EN//独立按键外部中断
	driver->WHT_Independent_Button_Exti_Flag = &WHT_Independent_Button_Exti_Flag;
	driver->WHT_Independent_Button_Exti_Config = WHT_Button_Driver_Independent_Button_Exti_Config;
	driver->WHT_Independent_Button_Exti_Enable = WHT_Independent_Button_Exti_Start;
#else
	driver->WHT_Independent_Button_Exti_Flag = NULL;
	driver->WHT_Independent_Button_Exti_Config = NULL;
	driver->WHT_Independent_Button_Exti_Enable = NULL;
#endif
#if Matrix_Button_EXTI_EN//矩阵按键外部中断
	driver->WHT_Matrix_Button_Col_Exti_Flag = &WHT_Matrix_Button_Col_Exti_Flag;
	driver->WHT_Matrix_Button_Exti_Config = WHT_Button_Driver_Matrix_Button_Col_Exti_Config;
	driver->WHT_Matrix_Button_Exti_Enable = WHT_Matrix_Button_Col_Exti_Start;
#else
	driver->WHT_Matrix_Button_Col_Exti_Flag = NULL;
	driver->WHT_Matrix_Button_Exti_Config = NULL;
	driver->WHT_Matrix_Button_Exti_Enable = NULL;
#endif
#if Independent_Button_EN//独立按键
	driver->WHT_Get_Independent_Button_State = WHT_Button_Driver_Get_Independent_Button_State;
	driver->WHT_Independent_Button_Scan = WHT_Button_Driver_Independent_Button_Scan;
#else
	driver->WHT_Get_Independent_Button_State = NULL;
	driver->WHT_Independent_Button_Scan = NULL;
#endif
#if Matrix_Button_EN//矩阵按键
	driver->WHT_Get_Matrix_Button_State = WHT_Button_Driver_Get_Matrix_Button_State;
	driver->WHT_Matrix_Button_Scan = WHT_Button_Driver_Matrix_Button_Scan;
#else
	driver->WHT_Get_Matrix_Button_State = NULL;
	driver->WHT_Matrix_Button_Scan = NULL;
#endif
}
